//
// * Copyright (c) 2002-2010 "Neo Technology,"
// *     Network Engine for Objects in Lund AB [http://neotechnology.com]
// *
// * This file is part of Neo4j.
// * 
// * Neo4j is free software: you can redistribute it and/or modify
// * it under the terms of the GNU Affero General Public License as
// * published by the Free Software Foundation, either version 3 of the
// * License, or (at your option) any later version.
// * 
// * This program is distributed in the hope that it will be useful,
// * but WITHOUT ANY WARRANTY; without even the implied warranty of
// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// * GNU Affero General Public License for more details.
// * 
// * You should have received a copy of the GNU Affero General Public License
// * along with this program. If not, see <http://www.gnu.org/licenses/>.
// 
#region Using Directives

using System.ComponentModel;

#endregion
namespace org.neo4j.graphdb
{
    ///
    /// <summary> * Defines relationship directions used when getting relationships from a node
    /// * or when creating traversers.
    /// * 
    ///   * A relationship has a direction from a node's point of view. If a node is the
    ///   * start node of a relationship it will be an <seealso cref="OUTGOING"/> relationship
    ///   * from that node's point of view. If a node is the end node of a relationship
    ///   * it will be an <seealso cref="INCOMING"/> relationship from that node's point of view.
    ///   * The <seealso cref="BOTH"/> direction is used when direction is of no importance, such
    ///   * as "give me all" or "traverse all" relationships that are either
    ///   * <seealso cref="OUTGOING"/> or <seealso cref="INCOMING"/>
    ///   . 
    /// </summary>
    public enum Direction
    {
        /// <summary>
        /// Defines outgoing relationships.
        /// </summary>
        OUTGOING,
        /// <summary>
        /// Defines incoming relationships.
        /// </summary>
        INCOMING,
        /// <summary>
        /// Defines both incoming and outgoing relationships.
        /// </summary>
        BOTH
    }
    #region Direction Extention Methods

    /// <summary>
    /// 
    /// </summary>
    public static class DirectionExtensions
    {
        /// <summary>
        /// 
        /// </summary>
        /// <param name="direction"></param>
        /// <returns></returns>
        public static string ToDescriptionString(this Direction direction)
        {
            DescriptionAttribute[] attributes = (DescriptionAttribute[])direction.GetType().GetField(direction.ToString()).GetCustomAttributes(typeof(DescriptionAttribute), false);
            return attributes.Length > 0 ? attributes[0].Description : string.Empty;
        }
        /// <summary>
        /// Reverses the direction returning <seealso cref="Direction.INCOMING"/> if this equals
        /// <seealso cref="Direction.OUTGOING"/>, <seealso cref="Direction.OUTGOING"/> if this equals <seealso cref="Direction.INCOMING"/> or
        ///  <seealso cref="Direction.BOTH"/> if this equals <seealso cref="Direction.BOTH"/>.
        /// </summary>
        /// <param name="direction"></param>
        /// <returns>The reversed direction.</returns>
        public static Direction Reverse(this Direction direction)
        {
            switch (direction)
            {
                case Direction.OUTGOING:
                    return Direction.INCOMING;
                case Direction.INCOMING:
                    return Direction.OUTGOING;
                case Direction.BOTH:
                    return Direction.BOTH;
                default:
                    throw new IllegalStateException("Unknown Direction " + "enum: " + direction);
            }
        }
    }

    #endregion
}